 
import { ABaseDecision } from "GameLoop/DecisionMaking/BaseDecision";
import { CoreEntity } from "GameLoop/WorldState/EntityManager/Entitys";
import { terminal_config } from "GameLoop/WorldState/EntityManager/Entitys/room/core/constants";
import { FactoryTaskHelper } from "GameLoop/WorldState/EntityManager/Entitys/room/factory/FactoryTaskHelper";
import { BASE_PRODUCE } from "GameLoop/WorldState/EntityManager/Entitys/room/factory/constants";
 
import { priority } from "utils/constants/definetypes";
import { ZipMinerial } from "utils/constants/globalconstant";
 
import { PositionHelper } from "utils/position/PositionHelper";
 

/**
 * core 的维护操作
 */
export class CoreStrategyDecision< T extends "creep"="creep"> extends ABaseDecision<T>
{

    public isExpired(event: NormalEvent, region: string): boolean 
    {

 
        const lordroom = Game.rooms[event.region] as Required<Room>;
        if(lordroom.controller.level<6 || lordroom.getTaskByType("core").length>0)
        {
            return false;
        }
        
        return true;
    }
    public makeTask(event: IFillStoreEvent, region: string): IDecisionCode<T>|false
    {
        // global.Log.Info(`维修任务`);
        const lordroom = Game.rooms[event.region] as Required<Room>;
  
        const coreEntity = lordroom.getEntity("CoreEntity");
        if(!coreEntity)
        {
            return false;
        }
        // link
        if(coreEntity.Link)
        {
            if(lordroom.canExecute(3) && this.tryTransferToSpawn(coreEntity))
            {
                return false;
            }
            if( lordroom.canExecute(10) && coreEntity.Link.store.getUsedCapacity(RESOURCE_ENERGY)>0)
            {
                coreEntity.transferOutTask(coreEntity.Link,{resourceType:RESOURCE_ENERGY,amount:coreEntity.Link.store.getUsedCapacity(RESOURCE_ENERGY)},"core_task");
                return false;
            }
            
        }

        if(lordroom.canExecute(10))
        {
            if(coreEntity.Storage && coreEntity.Terminal)
            {
                
                if(this.tryfillNuker(coreEntity))
                {
                    return false;
                }
                if(this.tryfillPowerSpawn(coreEntity))
                {
                    return false;
                }
                if(this.balanceSpace(coreEntity,coreEntity.Terminal,coreEntity.Storage))
                {
                    return false;
                }
                if(this.blacnceEnergy(coreEntity,coreEntity.Terminal,coreEntity.Storage))
                {
                    return false;
                }
                if(lordroom.canExecute(100) && lordroom.controller.level ==8 &&  lordroom.getTaskByType("factory").length ==0)
                {
                    if(coreEntity.Factory && !coreEntity.Factory.cooldown)
                    {
                        if(coreEntity.Factory.level )
                        {
                            if(this.tryProduceCommodities(coreEntity))
                            {
                                // 生产商品
                                return false
                            }
                        }
                        if(this.tryUnZipEnergy(coreEntity))
                        {   
                            // 优先判断能量不足的情况
                            return false
                        }
                        //  todo 加工基础商品
                        if(this.tryProduceBaseDepo(coreEntity))
                        {
                            return false;
                        }
    
                        if(this.tryZipEnergy(coreEntity))
                        {
                            // 要满了才去压缩.这里可能会opstorage导致错误
                            return false;
                        }
                        if(this.tryZipMinerial(coreEntity))
                        {
                            // 要满了才去压缩.这里可能会opstorage导致错误
                            return false;
                        }
                    }
                    if(lordroom.canExecute(5000)&& coreEntity.freeSpace()<100000)
                    {
                        this.pauseTask(lordroom);
                    }
                }
                
            }
        }
        return false;
    }
    
      /**
     * 平衡terminal的能量
     * @param terminal
     * @param Storage
     */
    private blacnceEnergy(core:CoreEntity,terminal:StructureTerminal,Storage:StructureStorage)
    {
        const transfer = terminal_config.energy_require;
        const exist_num = terminal.store.getUsedCapacity(RESOURCE_ENERGY);
        const storage_num = Storage.store.getUsedCapacity(RESOURCE_ENERGY);
        if(terminal.store.getUsedCapacity(RESOURCE_ENERGY)<transfer*0.8 && storage_num>1500)
        {
            const Left_amount = transfer-exist_num ;
            const amount_transfer =_.min([Left_amount,storage_num,terminal.store.getFreeCapacity()]);
            if(amount_transfer>1000  )
            {
                core.transferResource(Storage,terminal,[{resourceType:RESOURCE_ENERGY,amount: amount_transfer}],10);
                return true;
            }
        }
        return false;
    }
       /**
        * 平衡terminal和storage的空闲空间
        * @param terminal
        * @param Storage
        */
    public balanceSpace(core:CoreEntity,terminal:StructureTerminal,Storage:StructureStorage)
    {
        
        // 除了能量和商品外全都塞回 storage
        if(terminal.store.getFreeCapacity()>=50000)
        {
            return false;
        }
        const need_space = Math.ceil( terminal_config.space- terminal.store.getFreeCapacity());
        for(const key in terminal.store)
        {
            const store_amount = terminal.store.getUsedCapacity(key as ResourceConstant);
            if(key == RESOURCE_ENERGY)
            {
                if(store_amount>terminal_config.energy_require+10000)
                {
                core.transferResource(terminal,Storage,[{resourceType:RESOURCE_ENERGY,amount: Math.min(store_amount-terminal_config.energy_require,need_space)}],10);
                    return true;
                }
            }
            else if(! (  COMMODITIES[key as CommodityConstant]?.level))
            {
                // 是商品
                core.transferResource(terminal,Storage,[{resourceType:key as ResourceConstant,amount: Math.min(store_amount,need_space)}],10);
                return true;
            }
        }
        return false;
    }

     /**
      * 压缩能量
      * @param core 
      */
    private tryUnZipEnergy(core:CoreEntity)
    {
        if(core.resourceCount(RESOURCE_ENERGY)<50000 && core.resourceCount(RESOURCE_BATTERY)>1000)
        {
            const factorytask =  FactoryTaskHelper.getProduceTask( core.roomName,RESOURCE_ENERGY as CommodityConstant,10000);
            core.room.addNewTask(factorytask);
            return true;
        }
        return false;
    }
     /**
      * 压缩元素矿
      * @param core 
      * @returns 
      */
    private tryZipMinerial(core:CoreEntity)
    {
        if(core.freeSpace()>200000)
        {
            return false;
        }
        for(const e in ZipMinerial)
        {
            if(core.resourceCount(e as MineralConstant)>100000 )
            {
                const factorytask =  FactoryTaskHelper.getProduceTask( core.roomName,ZipMinerial[e as MineralConstant],2000);
                core.room.addNewTask(factorytask);
                return true;
            }
        }
        return false;
    }
    /**
     * 压缩能量
     * @param coreentity 
     * @returns 
     */
    private tryZipEnergy(coreentity:CoreEntity)
    {
        
        if(coreentity.resourceCount(RESOURCE_ENERGY)>180000 && coreentity.freeSpace()<100000 )
        {
            const factorytask =  FactoryTaskHelper.getProduceTask(coreentity.room.name, RESOURCE_BATTERY,2000);
            coreentity.room.addNewTask(factorytask);
            return true;
        }
        return false;
    }
        /**
     * 压缩能量
     * @param coreentity 
     * @returns 
     */
        private tryProduceBaseDepo(coreentity:CoreEntity)
        {
            
            let amount=1000
            for(const key in BASE_PRODUCE)
            {
                if(coreentity.isProduceResourceReady(key as CommodityConstant,10))
                {
                    let target:ITargetParam={target:key as CommodityConstant,amount:amount/5,number:0};
                    const factorytask =  FactoryTaskHelper.getProduceTask(coreentity.room.name, target.target,target.amount);
                    coreentity.room.addNewTask(factorytask);
                    return true
                }
    
            }
            return false;
        }

        private tryProduceCommodities(coreentity:CoreEntity)
        {
            const goal = coreentity.room.getNodeHeap().produceLineGoal;
            if(goal)
            {
                if( coreentity.isProduceReady(goal.resourceType))
                {
                    const factorytask =  FactoryTaskHelper.getProduceTask(coreentity.room.name, goal.resourceType,goal.amount);
                    coreentity.room.addNewTask(factorytask);
                    return true
                }
                else if(global.resourceStats.isCanbeProduce(goal.resourceType,goal.amount))
                {
                    const factorytask =  FactoryTaskHelper.getProduceTask(coreentity.room.name, goal.resourceType,1);
                    coreentity.room.addNewTask(factorytask);
                    return true
                }
                // coreentity.room.getNodeHeap().produceLineGoal = undefined;
            }
             
            return false;
        }

        
 /**
     * 压缩能量
     * @param coreentity 
     * @returns 
     */
    private tryTransferToSpawn(coreentity:CoreEntity)
    {
         
        const spawn = coreentity.getEntity('SpawnEntity');
        if(!spawn.Link ||spawn.Link.store.getUsedCapacity(RESOURCE_ENERGY)>100)
        {
            return false;
        }
        const rest = spawn.getStoreObjects({resourceType:RESOURCE_ENERGY,amount:2000});
        
        if(coreentity.resourceCount(RESOURCE_ENERGY)>20000 &&  rest.length )
        {
            coreentity.transferToLink(spawn.Link);
            return true;
        }
        return false;
    }
    public tryfillNuker(coreentity:CoreEntity)
    {
        const nuker = coreentity.Nuker;
        if(nuker&& nuker.cooldown<10000)
        {
            const need = nuker.store.getFreeCapacity(RESOURCE_GHODIUM);
            if(need>0)
            {

                const has = coreentity.getTakeStores({resourceType:RESOURCE_GHODIUM,amount:need});
                if(has.length>0)
                {
                    return  coreentity.transferResource(has[0],nuker,[{resourceType:RESOURCE_GHODIUM,amount:need}],1);
                }
            }
            {
                const need = nuker.store.getFreeCapacity(RESOURCE_ENERGY);
                if(need>0)
                {
                    const energy_amount = Math.min(need,7500);
                    const has = coreentity.getTakeStores({resourceType:RESOURCE_ENERGY,amount:energy_amount});
                    if(has.length>0)
                    {
                        return  coreentity.transferResource(has[0],nuker,[{resourceType:RESOURCE_ENERGY,amount:energy_amount}],1);
                    }
                }
            }
        }

       
        return false
    }

    // 100K以下就不烧power了
    
    public tryfillPowerSpawn(coreentity:CoreEntity)
    {
        if(coreentity.resourceCount(RESOURCE_ENERGY)<100000)
        {
            return false;
        }
        const PowerSpawn = coreentity.PowerSpawn;
        if(PowerSpawn)
        {
            coreentity.log('info',PowerSpawn.store.getFreeCapacity(RESOURCE_POWER),PowerSpawn.store.getCapacity(RESOURCE_POWER))
            const need = PowerSpawn.store.getFreeCapacity(RESOURCE_POWER);
            if(need == PowerSpawn.store.getCapacity(RESOURCE_POWER))
            {
                // 空的
                const has = coreentity.getTakeStores({resourceType:RESOURCE_POWER,amount:need});
                if(has.length>0)
                {
                    return  coreentity.transferResource(has[0],PowerSpawn,[{resourceType:RESOURCE_POWER,amount:need}],1);
                }
                else 
                {
                    coreentity.log('info','资源不足');
                }
            }
            {
                const need = PowerSpawn.store.getFreeCapacity(RESOURCE_ENERGY);
                if(need  == PowerSpawn.store.getCapacity(RESOURCE_ENERGY))
                {
                   
                    const has = coreentity.getTakeStores({resourceType:RESOURCE_ENERGY,amount:need});
                    if(has.length>0)
                    {
                        return  coreentity.transferResource(has[0],PowerSpawn,[{resourceType:RESOURCE_ENERGY,amount:need}],1);
                    }
                }
            }
        }

       
        return false
    }
    /**
     * 每次执行只暂停一个房间
     * @param room 
     */
    public pauseTask(room:Required<Room>)
    {
        
        // 1.先暂停中央房
        {
            const tasks =    room.getTaskByType("team");
            for(const e of tasks)
            {
                if(e.pause)
                {
                    continue;
                }
                if(!e.data.room || e.data.room == room.name)
                {
                    continue;
                }
                room.pauseTask(e,5000);
            }
        }
        
        // 2.再暂停普通的外矿房,只暂停采集
        {
            const tasks =    room.getTaskByType("creep");
            for(const e of tasks)
            {
                if(e.pause)
                {
                    continue;
                }
                if(!e.data.room || e.data.room == room.name)
                {
                    continue;
                }
                if(e.data.type == "harvest" ||e.data.type== "harvestM")
                {
                    room.pauseTask(e,5000);
                }
            }
        }
    }
}